﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Ndo
{
    public static class For<T>
    {
        public static IEnumerable<T> Inc(T begin, T end)
        {
            return Inc(begin, end, false, EqualityComparer<T>.Default);
        }
        public static IEnumerable<T> Inc(T begin, T end, IEqualityComparer<T> comparer)
        {
            return Inc(begin, end, false, comparer);
        }
        public static IEnumerable<T> Inc(T begin, T end, bool withEnd)
        {
            return Inc(begin, end, withEnd, EqualityComparer<T>.Default);
        }

        public static IEnumerable<T> Inc(T begin, T end, bool withEnd, IEqualityComparer<T> comparer)
        {
            T t = begin;
            while (!comparer.Equals(t, end))
            {
                yield return t;
                t = OperatorDelegates<T>.Increment(t);
            }
            if (withEnd && comparer.Equals(t, end))
                yield return t;
        }

        public static IEnumerable<T> Dec(T begin, T end)
        {
            return Dec(begin, end, false, EqualityComparer<T>.Default);
        }
        public static IEnumerable<T> Dec(T begin, T end, IEqualityComparer<T> comparer)
        {
            return Dec(begin, end, false, comparer);
        }
        public static IEnumerable<T> Dec(T begin, T end, bool withEnd)
        {
            return Dec(begin, end, withEnd, EqualityComparer<T>.Default);
        }

        public static IEnumerable<T> Dec(T begin, T end, bool withEnd, IEqualityComparer<T> comparer)
        {
            T t = begin;
            while (!comparer.Equals(t, end))
            {
                yield return t;
                t = OperatorDelegates<T>.Decrement(t);
            }
            if(withEnd && comparer.Equals(t, end))
                yield return t;
        }
    }

    public static class For
    {
        public static IEnumerable<Int32> Inc(Int32 begin, Int32 end)
        {
            for (Int32 i = begin; i < end; i++)
                yield return i;
        }
        public static IEnumerable<Int32> Inc(Int32 begin, Int32 end, bool withEnd)
        {
            Int32 i;
            for (i = begin; i < end; i++)
                yield return i;
            if (withEnd && i == end)
                yield return i;
        }
        public static IEnumerable<Int32> Dec(Int32 begin, Int32 end)
        {
            for (Int32 i = begin; i > end; i--)
                yield return i;
        
        }
        public static IEnumerable<Int32> Dec(Int32 begin, Int32 end, bool withEnd)
        {
            Int32 i;
            for (i = begin; i > end; i--)
                yield return i;
            if (withEnd && i == end)
                yield return i;
        }
        public static IEnumerable<Int64> Inc(Int64 begin, Int64 end)
        {
            for (Int64 i = begin; i < end; i++)
                yield return i;
        }
        public static IEnumerable<Int64> Inc(Int64 begin, Int64 end, bool withEnd)
        {
            Int64 i;
            for (i = begin; i < end; i++)
                yield return i;
            if (withEnd && i == end)
                yield return i;
        }
        public static IEnumerable<Int64> Dec(Int64 begin, Int64 end)
        {
            for (Int64 i = begin; i > end; i--)
                yield return i;
        }
        public static IEnumerable<Int64> Dec(Int64 begin, Int64 end, bool withEnd)
        {
            Int64 i;
            for (i = begin; i > end; i--)
                yield return i;
            if (withEnd && i == end)
                yield return i;
        }
    }

}
